package com.bestcem.xm.ticket.util;

import cn.hutool.core.lang.ObjectId;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.ticket.dao.TicketDao;
import com.bestcem.xm.ticket.entity.mongo.Ticket;
import com.bestcem.xm.ticket.enums.TicketStatusEnum;
import com.bestcem.xm.ticket.grpc.client.TicketBaseUserGrpcService;
import com.bestcem.xm.ticket.grpc.client.dto.user.UserDTO;
import org.springframework.stereotype.Component;

import javax.annotation.Nonnull;
import javax.annotation.Resource;
import java.util.*;

/**
 * 工单内部权限处理 工具类
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.com>
 * @version v1.0
 * @date 2022/1/5 13:57
 */
@Component
public class AuthorityUtil {

    @Resource
    private TicketBaseUserGrpcService ticketBaseUserGrpcService;

    @Resource
    private TicketDao ticketDao;

    @Resource
    private CommonUtils commonUtils;


    /**
     * 当前登录用户是否有权限查看对应工单
     *
     * @param ticketId 工单id
     * @param token    当前登录用户token信息
     * @return 是否有权限查看对应工单
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2022/1/5 14:30
     */
    public boolean hasLookPermission(String ticketId, @Nonnull TokenDTO token) {
        Ticket ticket = ticketDao.findById(ticketId);
        if (Objects.isNull(ticket)) {
            return false;
        }
        // 已删除的工单不能被查看
        if (TicketStatusEnum.DELETED.getIndex().equals(ticket.getStatus())) {
            return false;
        }
        UserDTO user = ticketBaseUserGrpcService.getUser(token.getUserId());
        if (Objects.isNull(user) || !ObjectId.isValid(user.getId())) {
            return false;
        }
        // 只能看当前租户的工单
        if (!ObjectId.isValid(user.getOrgId()) || !user.getOrgId().equals(ticket.getOrgId())) {
            return false;
        }
        // 超管可以看当前租户下所有工单
        if (Integer.valueOf(1).equals(token.getSuperRole())) {
            return true;
        }
        Set<String> userAllGroupIds = new HashSet<>(commonUtils.getUserAllGroupId(user.getId()));
        Set<String> roleIds = new HashSet<>(commonUtils.getUserAllRoleId(user.getId()));
        Set<String> userCurrentGroupIds = new HashSet<>(commonUtils.getUserCurrentGroupId(user.getId()));

        // 是否满足区域要求
        boolean isRegion = userAllGroupIds.contains(ticket.getRegion());
        // 是否满足创建人要求
        boolean isCreator = user.getId().equals(ticket.getCreatedId());
        // 是否满足当前处理人要求
        boolean isFollowUser = Optional.ofNullable(ticket.getCurFollowUserId()).orElse(new ArrayList<>()).contains(user.getId());
        // 是否满足跟进角色要求
        boolean isFollowRole = (Objects.isNull(ticket.getRegion()) || userCurrentGroupIds.contains(ticket.getRegion())) && roleIds.contains(ticket.getFollowRoleId());
        // 是否满足审核角色要求
        boolean isAuditRole = (Objects.isNull(ticket.getRegion()) || userCurrentGroupIds.contains(ticket.getRegion())) && roleIds.contains(ticket.getAuditRoleId());
        // 是否满足已跟进人要求
        boolean isFollowed = Optional.ofNullable(ticket.getFollowUserIds()).orElse(new ArrayList<>()).contains(user.getId());
        // 是否满足已审核人要求
        boolean isAudited = Optional.ofNullable(ticket.getAuditUserIds()).orElse(new ArrayList<>()).contains(user.getId());

        // 所有要求满足一个就可以查看当前工单
        return isRegion || isCreator || isFollowUser || isFollowRole || isAuditRole || isFollowed || isAudited;
    }
}
